package com.greenline.search.report.model;

import com.greenline.search.report.entity.LogReportResult;
import com.greenline.search.report.entity.ReportEntity;
import com.greenline.search.report.entity.SearchWord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: liulei
 * Date: 14-2-13
 * Time: 下午3:04
 * To change this template use File | Settings | File Templates.
 */
public class GenerateReportResult {

    private static Logger logger = LoggerFactory.getLogger(GenerateReportResult.class);
    //上周报告
    private LogReportResult currentWeekReportResult;
    //上周搜索关键词列表
    private List<SearchWord> currentWeekSearchWordList;

    public GenerateReportResult(List<SearchWord> currentWeekSearchWordList,
                                List<SearchWord> lastWeekSearchWordList){
        this.currentWeekSearchWordList = currentWeekSearchWordList;
        currentWeekReportResult = new LogReportResult();
        //搜索关键词列表按照搜索频次排序
        Collections.sort(currentWeekSearchWordList);
        Collections.sort(lastWeekSearchWordList);
        logger.info("Deal with the rank list...");
        //填充相应实体搜索热度相关信息
        for(ReportEntity entity : ReportEntity.values()){
            generateEntityReport(entity,true);
        }
        logger.info("Deal with the up rank list...");

        //设置搜索关键词rank相关信息
        for(int i = 0; i < currentWeekSearchWordList.size(); i++){
            SearchWord searchWord = currentWeekSearchWordList.get(i);
            searchWord.setCurrentWeekRank(i+1);
            if(lastWeekSearchWordList.contains(searchWord)){
                searchWord.setLastWeekRank(lastWeekSearchWordList.indexOf(searchWord)+1);
            }else {
                searchWord.setLastWeekRank(0);
            }
            searchWord.setRankDifference(
                    searchWord.getLastWeekRank() - searchWord.getCurrentWeekRank());
            currentWeekSearchWordList.set(i,searchWord);
        }

        logger.info("Deal with the up rank difference...");
        //搜索关键词列表按照rankDifference进行排序
        Collections.sort(currentWeekSearchWordList,new RankDifferenceComparator());
        //填充相应实体上升排名相关信息

        int count = 0;
        for(ReportEntity entity : ReportEntity.values()){
            String type = entity.name().toLowerCase();
            for(SearchWord word : currentWeekSearchWordList){
                if(word.getTypeArray().length == 1 && word.getTypeArray()[0].equals(type) && word.getFrequency() > 50){
                    count++;
                }
            }
            logger.info("The count of search word about {} is {}", type, count);
        }


        for(ReportEntity entity : ReportEntity.values()){
            generateEntityReport(entity,false);
        }
        logger.info("Generate the report list done.");
    }

    //填充相应的实体列表
    private void generateEntityReport(ReportEntity entity,boolean flag){
        List<SearchWord> entityList = new LinkedList<SearchWord>();
        int loopCount = Configuration.EVERY_ENTITY_LIST_COUNT;
        //总榜只要取前loopCount个即可
        if(entity == ReportEntity.OVERALL){
            for(int i = 0; i < currentWeekSearchWordList.size(); i++){
                if(currentWeekSearchWordList.get(i).getFrequency() > Configuration.MIN_FREQUENCY){
                    entityList.add(currentWeekSearchWordList.get(i));
                }
                if(entityList.size() >= loopCount){
                    break;
                }
            }
        }else {
            //其他entity则从头取相应的entity
            String type = entity.name().toLowerCase();
            for(int i = 0; i < currentWeekSearchWordList.size(); i++){
                SearchWord searchWord = currentWeekSearchWordList.get(i);
                if(searchWord.getTokenArray().length == 1
                        && searchWord.getTypeArray()[0].equals(type) &&
                        searchWord.getFrequency() > Configuration.MIN_FREQUENCY){
                    entityList.add(searchWord);
                }
                //如果已经达到需要的数量则终止循环
                if (entityList.size() >= loopCount){
                    break;
                }
            }
        }
        switch (entity){
            case OVERALL:
                if(flag)
                    currentWeekReportResult.setOverallRankedList(entityList);
                else
                    currentWeekReportResult.setOverallUpList(entityList);
                break;
            case DOCTOR:
                if(flag)
                    currentWeekReportResult.setDoctorRankedList(entityList);
                else
                    currentWeekReportResult.setDoctorUpList(entityList);
                break;
            case DISEASE:
                if (flag)
                    currentWeekReportResult.setDiseaseRankedList(entityList);
                else
                    currentWeekReportResult.setDiseaseUpList(entityList);
                break;
            case HOSPITAL:
                if(flag)
                    currentWeekReportResult.setHospitalRankedList(entityList);
                else
                    currentWeekReportResult.setHospitalUpList(entityList);
                break;
            case DEPARTMENT:
                if(flag)
                    currentWeekReportResult.setDepartmentRankedList(entityList);
                else
                    currentWeekReportResult.setDepartmentUpList(entityList);
                break;
            default:
                logger.error("Emerge the wrong entity: %s",entity.name());
        }
    }

    public LogReportResult getCurrentWeekReportResult() {
        return currentWeekReportResult;
    }
}

class RankDifferenceComparator implements Comparator{
    @Override
    public int compare(Object o1, Object o2) {
        SearchWord searchWord1 = (SearchWord)o1;
        SearchWord searchWord2 = (SearchWord)o2;
        if(searchWord1.getRankDifference() > searchWord2.getRankDifference()){
            return -1;
        } else if(searchWord1.getRankDifference() < searchWord2.getRankDifference()){
            return 1;
        }else {
            return 0;
        }
    }
}
